package com.cam.framework.utils;

import cn.hutool.core.util.StrUtil;
import com.cam.framework.annotation.SysDictAnno;
import com.cam.framework.crud.SysDictInterface;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

@Component
public class DictUtils {

    public static void refreshDictMap() {
        // 定义类扫描对象
        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
        // 扫描带有 SysDictAnnotation 注解的类
        scanner.addIncludeFilter(new AnnotationTypeFilter(SysDictAnno.class));
        Set<BeanDefinition> dictSet = scanner.findCandidateComponents("com.cam");

        HashMap<String, Object> dictMap = new HashMap<>();
        for (BeanDefinition eachBean : dictSet) {
            try {
                // 获取对应的 Class 对象
                Class<?> dictClass = Class.forName(eachBean.getBeanClassName());
                // 判断是否继承了 CrudDict，以及是否为枚举类
                if (SysDictInterface.class.isAssignableFrom(dictClass) && dictClass.isEnum()) {
                    // item: {label, value}
                    HashMap<String, Object> itemMap = new HashMap<>();
                    // 获取该字典枚举类下所有以 get 开头的类方法
                    List<Method> enumMethodList = Arrays.stream(dictClass.getDeclaredMethods()).filter(method -> method.getName().startsWith("get")).collect(Collectors.toList());
                    // 获取该字典枚举类下所有枚举实例
                    Enum<?>[] enumArray = (Enum<?>[]) dictClass.getEnumConstants();
                    // 循环字典枚举类下所有枚举实例
                    for (Enum<?> eachEnum : enumArray) {
                        // {label: label, value: value}
                        HashMap<String, Object> eachMap = new HashMap<>();
                        for (Method eachMethod : enumMethodList) {
                            // 循环将字典枚举类下所有 get 方法
                            eachMap.put(StringUtils.uncapitalize(eachMethod.getName().replace("get", "")), eachMethod.invoke(eachEnum));
                        }
                        itemMap.put(eachEnum.name(), eachMap);
                    }
                    // 最终形成 {dictName: {itemName1: {label: label, value: value}, itemName2: {label: label, value: value}}}的格式
                    String dictName = StrUtil.toUnderlineCase(dictClass.getSimpleName().replaceAll("Dict$", "")); // 默认替换掉类名结尾的 Dict，将类名作为 map key，
                    for (Annotation eachAnno : dictClass.getAnnotations()) {
                        // 遍历该字典类的所有注解
                        if (eachAnno instanceof SysDictAnno) {
                            // 找到SysDictAnno注解
                            if (StringUtils.isNotEmpty(((SysDictAnno) eachAnno).type())) {
                                // 如果该注解标明了type，则使用type的值为dictName
                                dictName = ((SysDictAnno) eachAnno).type();
                            }
                        }
                    }
                    dictMap.put(dictName, itemMap);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        CacheUtils.setCache("dictMap", dictMap);
    }

    public static HashMap<String, List<HashMap<String, Object>>> getDictMap() {
//        return (HashMap<String, List<HashMap<String, Object>>>) CacheUtil.getCache("dictMap");
        return CacheUtils.getCache("dictMap", HashMap.class);
    }
}
